#include "convert.h"
#include "stdio.h"
#include "string.h"
#include "stdlib.h"

Convert::Convert()
{

}

void Convert::Ascii2Hex(uint8_t *outBuffer, uint8_t *inBuffer, uint32_t len)
{
    uint32_t i;
    uint8_t temp;
    for (i = 0; i<len; i++)
    {
        temp = inBuffer[2 * i];
        if (temp < 0x40)
            outBuffer[i] = (temp - 0x30) << 4;
        else
            outBuffer[i] = (temp - 0x41 + 0x0A) << 4;
        temp = inBuffer[2 * i + 1];
        if (temp < 0x40)
            outBuffer[i] |= (temp - 0x30) & 0x0F;
        else
            outBuffer[i] |= (temp - 0x41 + 0x0A) & 0x0F;

        //    //下面的有问题，对有些输入，输出不对
        //    temp = inBuffer[2*i+1];
        //		if(temp < 0x40)
        //			outBuffer[i] |= (temp-0x30);
        //		else
        //			outBuffer[i] |= (temp-0x41+0x0A);
    }
}

void Convert::Hex2Ascii(uint8_t *outBuffer, uint8_t *inBuffer, uint32_t len)
{
    uint32_t i;
    uint8_t temp;
    for (i = 0; i < len; i++)
    {
        temp = (inBuffer[i] & 0xF0) >> 4;
        if (temp < 0x0A)
            outBuffer[2 * i] = temp + 0x30;
        else
            outBuffer[2 * i] = temp - 0x0A + 0x41;

        temp = inBuffer[i] & 0x0F;
        if (temp < 0x0A)
            outBuffer[2 * i + 1] = temp + 0x30;
        else
            outBuffer[2 * i + 1] = temp - 0x0A + 0x41;
    }
    outBuffer[2 * i] = '\0';
}

//BCD码转10进制,len表示BCD码的长度
uint8_t Convert::BCD2Int(uint32_t *outNum, uint8_t *inBuffer, uint8_t len)
{
    uint8_t i;
    uint32_t temp = 0;
    for (i = 0; i < len; i++)
    {
        temp *= 10;
        if (inBuffer[i] >= '0' && inBuffer[i] <= '9')
            temp += (inBuffer[i] - '0');
        else
            return 1;
    }
    *outNum = temp;
    return 0;
}

//Int转BCD码,len表示BCD码的长度
void Convert::Int2BCD(uint8_t *outBuffer, uint32_t inNum, uint8_t len)
{
    uint8_t i, temp;
    for (i = 0; i < len; i++)
    {
        temp = inNum % 10;
        outBuffer[len - 1 - i] = temp + 0x30;
        inNum /= 10;
    }
}

uint32_t Convert::BCD2UInt(uint8_t*inBuffer, uint8_t len)
{
    uint32_t tmp = 0;
    for (int i = 0; i < len; i++)
    {
        tmp *= 10;

        if (inBuffer[0] >= '0' && inBuffer[0] <= '9')
        {
            tmp += (inBuffer[i] - '0');
        }
        else
        {
            return 0xFFFFFFFF;
        }
    }
    return tmp;
}

//清博华的BCD码转10进制，len表示BCD码的长度，一个BCD码如果不够6位，则前面为空格（0x20）
uint8_t Convert::QBH_BCD2Int(uint32_t *outNum, uint8_t *inBuffer, uint8_t len)
{
    uint8_t i, flag = 0;
    uint32_t temp = 0;
    for (i = 0; i < len; i++)
    {
        if (flag == 0)
        {
            if (inBuffer[i] == 0x20)
                continue;
            else if (inBuffer[i] >= '0' && inBuffer[i] <= '9')
                flag = 1;
            else
                return 1;
        }

        temp *= 10;
        if (inBuffer[i] >= '0' && inBuffer[i] <= '9')
            temp += (inBuffer[i] - '0');
        else
            return 1;
    }
    *outNum = temp;
    return 0;
}

//清博华的Int转BCD码,len表示BCD码的长度，如果一个int转成BCD码后不够6位，则前面补空格（0x20）
void Convert::QBH_Int2BCD(uint8_t *outBuffer, uint32_t inNum, uint8_t len)
{
    uint8_t i, temp;
    for (i = 0; i < len; i++)
    {
        if (inNum > 0)
        {
            temp = inNum % 10;
            outBuffer[len - 1 - i] = temp + 0x30;
            inNum /= 10;
        }
        else
            outBuffer[len - 1 - i] = 0x20; //前面补空格
    }
}

//SparkLinkProtocol的BCD码转10进制，len表示BCD码的长度，一个BCD码如果不够6位，则前面为空格（0x20）
uint32_t Convert::SparkLinkProtocol_BCD2Int(uint8_t *inBuffer, uint8_t len, uint8_t *ok)
{
    uint8_t i, flag = 0;
    uint32_t temp = 0;
    if (ok)
        *ok = 1;
    for (i = 0; i < len; i++)
    {
        if (flag == 0)
        {
            if (inBuffer[i] == 0x20)
                continue;
            else if (inBuffer[i] >= '0' && inBuffer[i] <= '9')
                flag = 1;
            else
            {
                if (ok)
                    *ok = 0;
                break;
            }
        }

        temp *= 10;
        if (inBuffer[i] >= '0' && inBuffer[i] <= '9')
            temp += (inBuffer[i] - '0');
        else
        {
            if (ok)
                *ok = 0;
            break;
        }
    }
    return temp;
}

//SparkLinkProtocol的Int转BCD码,len表示BCD码的长度，如果一个int转成BCD码后不够6位，则前面补空格（0x20）
void Convert::SparkLinkProtocol_Int2BCD(uint8_t *outBuffer, uint32_t inNum, uint8_t len)
{
    uint8_t i, temp;
    for (i = 0; i < len; i++)
    {
        if (inNum > 0)
        {
            temp = inNum % 10;
            outBuffer[len - 1 - i] = temp + 0x30;
            inNum /= 10;
        }
        else
            outBuffer[len - 1 - i] = 0x20; //前面补空格
    }
}

//字符串（十进制）/字符串（十六进制）转十六进制，最长转成一个int32_t
//装换完成是小端模式
int32_t Convert::String2Int32(char *in)
{
#if 1
    int32_t value = 0;
    if(in[0] == '0' && (in[1] == 'x' || in[1] == 'X'))
    {
        int len = strlen(in + 2);
        if(!(len % 2))
            Ascii2Hex((uint8_t*)(&value), (uint8_t*)(in + 2), len / 2);
        else
        {
            in[1] = '0';
            Ascii2Hex((uint8_t*)(&value), (uint8_t*)(in + 1), len / 2 + 1);
        }
    }
    else
    {
        value = ((int32_t)atoi(in));
    }
    return value;
#endif

#if 0
    int32_t v = 0;
    sscanf((const char *)in, "%d", &v);
    return v;
#endif

}

float Convert::String2Float(char *in)
{
#if 0
    char *s = in;
    float rez = 0, fact = 1;
    if (*s == '-')
    {
        s++;
        fact = -1;
    }

    for (int point_seen = 0; *s; s++)
    {
        if (*s == '.')
        {
            point_seen = 1;
            continue;

        }
        int d = *s - '0';
        if (d >= 0 && d <= 9)
        {
            if (point_seen)
                fact /= 10.0f;
            rez = rez * 10.0f + (float)d;
        };
    };
    return rez * fact;
#endif

#if 1
    return atof(in);
#endif

#if 0
    float v = 0;
    sscanf((const char *)in, "%f", &v);
    return v;
#endif

}
